import { isArray, isFunction, set } from "lodash";
import { getDicts } from "@/api/system/dict/data";
import tool from "@/utils/tool";
import request from "@/utils/request";

export const allowUseDictComponent: string[] = [
  "radio",
  "checkbox",
  "select",
  "transfer",
  "treeSelect",
  "tree-select",
  "cascader",
  "tree"
];

export const allowCoverComponent: string[] = ["radio", "checkbox", "select", "transfer", "cascader"];

export const loadDict = async (dictList: any, item: any, sourceList = [], maFormObject = {}): Promise<void> => {
  if (!allowUseDictComponent.includes(item.formType)) {
    return;
  }
  const dataIndex = item.parentDataIndex ? `${item.parentDataIndex}.${item.dataIndex}` : item.dataIndex;
  // 通过字典名称查询
  if (item.dict.name) {
    const dictData = tool.local.get("dictData") ?? {};
    if (item.dict.cache && dictData[dataIndex]) {
      dictList[dataIndex] = handlerDictProps(item, dictData[dataIndex]);
    } else {
      const { data } = await getDicts(item.dict.name);
      dictList[dataIndex] = handlerDictProps(item, data);
      if (item.dict.cache) {
        dictData[dataIndex] = data;
        tool.local.set("dictData", dictData);
      }
    }
  } else if (item.dict.remote) {
    let requestData = {
      openPage: item.dict?.openPage ?? false,
      remoteOption: item.dict.remoteOption ?? {}
    };
    requestData = Object.assign(requestData, item.dict.pageOption);
    if (requestData.openPage) {
      const { data } = await requestDict(item.dict.remote, "POST", {}, requestData);
      dictList[dataIndex] = handlerDictProps(item, data.items);
      dictList[dataIndex].pageInfo = data.pageInfo;
    } else {
      const dictData = tool.local.get("dictData") ?? {};
      if (item.dict.cache && dictData[dataIndex]) {
        dictList[dataIndex] = handlerDictProps(item, dictData[dataIndex]);
      } else {
        const { data } = await requestDict(item.dict.remote, "POST", {}, requestData);
        dictList[dataIndex] = handlerDictProps(item, data);
        if (item.dict.cache) {
          dictData[dataIndex] = data;
          tool.local.set("dictData", dictData);
        }
      }
    }
  } else if (item.dict.url) {
    let requestData = {
      openPage: item.dict?.openPage ?? false,
      remoteOption: item.dict.remoteOption ?? {}
    };
    requestData = Object.assign(requestData, item.dict.pageOption);
    if (requestData.openPage) {
      if (item.dict?.method === "GET" || item.dict?.method === "get") {
        item.dict.params = Object.assign(item.dict.params ?? {}, requestData);
      } else {
        item.dict.body = Object.assign(item.dict.body ?? {}, requestData);
      }
      const { data } = await requestDict(item.dict.url, item.dict.method || "GET", item.dict.params || {}, item.dict.body || {});
      dictList[dataIndex] = handlerDictProps(item, data.items);
      dictList[dataIndex].pageInfo = data.pageInfo;
    } else {
      const dictData = tool.local.get("dictData") ?? {};
      if (item.dict.cache && dictData[dataIndex]) {
        dictList[dataIndex] = handlerDictProps(item, dictData[dataIndex]);
      } else {
        const { data } = await requestDict(
          item.dict.url,
          item.dict.method || "GET",
          item.dict.params || {},
          item.dict.body || {}
        );
        dictList[dataIndex] = handlerDictProps(item, data);
        if (item.dict.cache) {
          dictData[dataIndex] = data;
          tool.local.set("dictData", dictData);
        }
      }
    }
  } else if (item.dict.data) {
    if (isArray(item.dict.data)) {
      dictList[dataIndex] = handlerDictProps(item, item.dict.data);
    } else if (isFunction(item.dict.data)) {
      const response = await item.dict.data();
      dictList[dataIndex] = handlerDictProps(item, response);
    }
  }
};

export const handlerCascader = async (val: any, column: any, columns: any, dictList: any, formModel: any, clearData = true) => {
  if (column.cascaderItem && isArray(column.cascaderItem)) {
    column.cascaderItem.map(async (name: any) => {
      const columnItem = columns.find((col: any) => col.dataIndex === name && col.dict);
      const dataIndex = columnItem.parentDataIndex
        ? `${columnItem.parentDataIndex}.${columnItem.dataIndex}`
        : columnItem.dataIndex;
      clearData && set(formModel, dataIndex, undefined);
      await requestCascaderData(val, columnItem.dict, dictList, dataIndex);
    });
  }
};
const requestCascaderData = async (val: any, dict: any, dictList: any, name: any) => {
  if (dict && (dict.remote || dict.url)) {
    let requestData = { openPage: dict?.openPage ?? false, remoteOption: dict.remoteOption ?? {} };
    let response;
    const pageOption = Object.assign(requestData, dict.pageOption);
    let url = dict.remote ?? dict.url;
    if (dict && url.indexOf("{{key}}") > 0) {
      url = url.replace("{{key}}", val);
      // 解析参数
      let queryParams = tool.getRequestParams(url);
      let urlIndex = url.indexOf("?");
      if (urlIndex !== -1) {
        url = url.substring(0, urlIndex);
      }
      response = await requestDict(
        url,
        dict.method ?? "GET",
        Object.assign(dict.params || {}, requestData.openPage ? pageOption : {}, queryParams),
        Object.assign(dict.data || {}, requestData.openPage ? pageOption : {})
      );
    } else {
      let temp = Object.assign({ key: val }, requestData.openPage ? pageOption : {});
      const params = Object.assign(dict.params || {}, temp);
      const data = Object.assign(dict.data || {}, temp);
      response = await requestDict(url, dict.method ?? "GET", params || {}, data || {});
    }
    if (response.data && response.code === 200) {
      let dataItems = requestData.openPage ? response.data.items : response.data;
      dictList[name] = dataItems.map((dicItem: any) => {
        return {
          label: dicItem[(dict.props && dict.props.label) || "label"],
          value: dicItem[(dict.props && dict.props.value) || "value"],
          disabled: typeof dicItem["disabled"] == "undefined" ? false : dicItem["disabled"] === true,
          indeterminate: typeof dicItem["indeterminate"] == "undefined" ? false : dicItem["indeterminate"] === true
        };
      });
      dictList[name].pageInfo = response.data.pageInfo ?? undefined;
    } else {
      console.error(response);
    }
  }
};

export const handlerDictProps = (item: any, tmpArr: any) => {
  let data: any = [];
  let tran: any = {};
  let colors: any = {};
  let labelName = "label";
  let valueName = "value";
  if (item?.dict?.name && (!item.dict.url || !item.dict.data)) {
    labelName = "title";
    valueName = "key";
  }
  if (allowCoverComponent.includes(item.formType)) {
    data = tmpArr.map((dicItem: any) => {
      const label = dicItem[(item.dict.props && item.dict.props.label) || labelName];
      let tmp = dicItem[(item.dict.props && item.dict.props.value) || valueName];
      let value;
      if (item.dict.name || item.dict.data) {
        value = tmp?.toString() ?? tmp;
      } else if (tmp === "true") {
        value = true;
      } else if (tmp === "false") {
        value = false;
      } else {
        value = tmp;
      }
      tran[value] = label;
      colors[value] = dicItem.listClass;
      return { label, value };
    });
  } else {
    data = tmpArr;
  }
  data.tran = tran;
  data.colors = colors;
  return data;
};

export const requestDict = (url: any, method: any, params: any, data: any, headers = {}, timeout = 60 * 1000) => {
  return request({ url, headers, method, params, data, timeout });
};
